Math.percent = function(value, from){
    return (value/from)*100;
};

Math.valueOfpercent = function (percent, value){
    return (value*percent)/100;
};

Math.getRandomInt = function(min, max){
	return Math.floor(Math.random() * (max - min + 1)) + min;
};

var Ship = (function(){

	function Ship(context, lifeContext){
		this._lifes = 4;
		this.lifes = [];
        this._deg = 0;
        this._x = 0;
        this._y = 0;
		this.context = context || document.body;
		this.lifesContext = lifeContext || document.getElementById("lifes");
	}

	Ship.prototype.create = function(element){
		var _this = this;
		this.element = element || document.createElement("figure");
		this.element.classList.add("ship");
		this.element.addEventListener("webkitAnimationEnd", function(){
			if(this.classList.contains("reset")){
				this.classList.remove("reset");
			}
		});
		this.element.addEventListener("webkitTransitionEnd", function(){
			if(this.classList.contains("damaged")){
				setTimeout(function(){
					_this.element.classList.remove("damaged");
				}, 1000);
			}
            if(this.classList.contains("left")) this.classList.remove("left");
            if(this.classList.contains("right")) this.classList.remove("right");
		});
		for(var i = 0; i < this._lifes; i++){
			var life = new Life(this.lifesContext);
			life.create();
			this.lifes.push(life);
		}
		this.context.appendChild(this.element);
	};

	Ship.prototype.destroy = function(){
		this.lifes[this.lifes.length-1].remove();
		this._lifes = this.lifes.length--;
		this.element.classList.add("damaged");
	};

	Ship.prototype.reset = function(){
		this.element.style.top = (this._y = window.innerHeight - this.element.offsetHeight * 2) + "px";
		this.element.style.left = (this._x = (window.innerWidth/2 - this.element.offsetWidth/2)) +"px";
		this.element.classList.add("reset");
	};

    Ship.prototype.move = function(deg){
        var step = Math.valueOfpercent(Math.percent(deg, 20), window.innerWidth / 2),
            max_right = ((window.innerWidth/2) - this.element.offsetWidth);
        console.log(deg > 0, step);



        if(deg > 0 && (deg > this._deg+4 || deg < this._deg-4)){
            if(step > (window.innerWidth/2)) step = (window.innerWidth/2);
            if(this._x > step){
                this.element.classList.add("right");
                this.element.classList.remove("left");
            }else if(this._x < step){
                this.element.classList.add("left");
                this.element.classList.remove("right");
            }
            this.element.style.left = (window.innerWidth/2) - (this._x = step) +"px";
            this._deg = deg;
        }else if(deg < 0 && (deg > this._deg+4 || deg < this._deg-4)){
            if(step < -max_right) step = -max_right;
            if(this._x > step){
                this.element.classList.add("right");
                this.element.classList.remove("left");
            }else if(this._x < step){
                this.element.classList.add("left");
                this.element.classList.remove("right");
            }
            this.element.style.left = (window.innerWidth/2) - (this._x = step) +"px";
            this._deg = deg;
        }
    };

	Ship.prototype.lifes = function(){
		this._lifes = 3;
	};

	Ship.prototype.shot = function(){
		if(this.element.classList.contains("damaged")) return;
		var bullet = new Bullet();
		bullet.create();
		bullet.fly(this.element.offsetLeft + (this.element.offsetWidth/2), this.element.offsetTop);
	};

	return Ship;

})();

var Life = (function(){

	function Life(context){
		this.context = context || document.body;
	}

	Life.prototype.create = function(element){
		var _this = this;
		this.element = element || document.createElement("div");

		this.element.addEventListener("webkitTransitionEnd", function(){
			if(this.classList.contains("remove")){
				_this.context.removeChild(this);
			}
		});

		this.context.appendChild(this.element);
	};

	Life.prototype.remove = function(){
		this.element.classList.add("remove");
	};

	return Life;

})();

var Bullet = (function(){

	function Bullet(context){
		this.context = context || document.body;
	}

	Bullet.prototype.create = function(element, type){
        var _this = this;
		this.element = element || document.createElement("figure");

        this.element.addEventListener("webkitTransitionEnd", function(){
            _this.context.removeChild(this);
        });

        this.element.classList.add("bullet");
		if(this.type = type) this.element.classList.add(type);
		this.context.appendChild(this.element);

	};

	Bullet.prototype.fly = function(x, y){
		var _this = this;
		this.setPosition(x, y);
		setTimeout(function(){
			_this.element.classList.add("fly");
		}, 1);
	};

	Bullet.prototype.setPosition = function(x, y){
		this.element.style.top = y - this.element.offsetHeight+"px";
		this.element.style.left = x - (this.element.offsetWidth/2)+"px";
	};

	return Bullet;

})();

var Enemy = (function(){

	function Enemy(context){
		this.speed = 3;
		this._y = 0;
		this._x = 0;
		this.shotTimeout = void 0;
		this.context = context || document.body;
	}

	Enemy.prototype.create = function(element){
		var _this = this;
		this.element = element || document.createElement("figure");
		this.element.classList.add("enemy");
		this.element.addEventListener("webkitAnimationEnd", function(){
			if(this.classList.contains("destroy")){
				this.classList.remove("destroy");
				_this.context.removeChild(this);
			}
			if(this.classList.contains("move")){
				this.classList.remove("move");
				_this.destroy();
			}
		});
		this.context.appendChild(this.element);
	};

	Enemy.prototype.go = function(){
		var _this = this;
		this.element.style.top = (this._y = -this.element.offsetHeight) + "px";
		this.element.style.left = (this._x = Math.getRandomInt(0, window.innerWidth - this.element.offsetWidth)) + "px";

		this.element.classList.add("move");
		setTimeout(function(){
			_this.element.style.top = window.innerHeight + _this.element.offsetHeight + "px";
		}, 1);
	};

	Enemy.prototype.shot = function(){
		var bullet = new Bullet();
		bullet.create(null, "red");
		bullet.fly(this.element.offsetLeft + (this.element.offsetWidth/2), this.element.offsetTop+this.element.offsetHeight);
	};

	Enemy.prototype.shoting = function(itervals){
		var _this = this;
		(function interval(){
			setTimeout(function(){
				_this.shot();
				interval();
			}, Math.getRandomInt(itervals[0], itervals[1]));
		})();
	};

	Enemy.prototype.destroy = function(){
		this.element.classList.add("destroy");
	};

	return Enemy;

})();

var Level = (function(){
	function Level(data){
		this.interval = void 0;
		this.enemies = [];
		if(data) this.load(data);
	}

	Level.prototype.load = function(data){
		this.data = data;
	};

	Level.prototype.start = function(){
		var _this = this, enemy;
		(function interval(){
			setTimeout(function(){
				enemy = new Enemy();
				enemy.create();
				enemy.go();
				enemy.shoting(_this.data.shotInterval);
				_this.enemies.push(enemy);

				interval();
			}, Math.getRandomInt(_this.data.enemyInterval[0], _this.data.enemyInterval[1])*1000);
		})();
	};

	return Level;
})();

var levels = [
	{
		enemies: 10,
		shotInterval: [700, 1300], //in milliseconds
		enemyInterval: [5,8] //in seconds
	}
];

var game = {

	start: function(){
		var context = document.body,
			shotInterval = void 0,
			ship = new Ship(),
			level = new Level();

		ship.create();
		ship.reset();
		context.classList.add("start");

		level.load(levels[0]);
		level.start();

		this.ship = ship;

        window.addEventListener("touchstart", function(){
            if(!shotInterval) ship.shot();
            shotInterval = setInterval(function(){
                ship.shot();
            }, 300);
        });
		window.addEventListener("touchend", function(){
			if(!shotInterval) ship.shot();
            clearInterval(shotInterval);
            shotInterval = void 0;
		});

        window.addEventListener("mousedown", function(){
            if(!shotInterval) ship.shot();
            shotInterval = setInterval(function(){
                ship.shot();
            }, 300);
        });
        window.addEventListener("mouseup", function(){
            if(!shotInterval) ship.shot();
            clearInterval(shotInterval);
            shotInterval = void 0;
        });
        window.addEventListener("mouseout", function(){
            clearInterval(shotInterval);
            shotInterval = void 0;
        });

        function deviceOrientationHandler(lr, fb, dir){
            ship.move(lr);
        }

        if (window.DeviceOrientationEvent) {
            window.addEventListener('deviceorientation', function(eventData) {
                // gamma is the left-to-right tilt in degrees, where right is positive
                var tiltLR = eventData.gamma;

                // beta is the front-to-back tilt in degrees, where front is positive
                var tiltFB = eventData.beta;

                // alpha is the compass direction the device is facing in degrees
                var dir = eventData.alpha

                // call our orientation event handler
                deviceOrientationHandler(tiltLR, tiltFB, dir);
            }, false);
        }
	}

};